#!/usr/bin/python


import random
from typing import Any

from paho.mqtt import client as mqtt_client

import time

import json
from log_class import Logger


# broker = '127.0.0.1'
# port = 1883
# # generate client ID with pub prefix randomly
# client_id = f'python-mqtt-{random.randint(0, 100)}'

log = Logger('log_record.log', level='debug')


class WuxiMqttClass:
    
    def __init__(self, broker, port, client_id) -> None:
        self.broker = broker
        self.port = port
        self.client_id = client_id
        self.client = self.connect_mqtt()
        # self.client.loop_start()
        # self.client.loop_forever()
        
    def on_connect(self, client, userdata, flags, rc):
        if rc == 0:
            # print("Connected to MQTT Broker!")
            log.logger.info("Connected to MQTT Broker!")
        else:
            # print("Failed to connect, return code %d\n", rc)
            log.logger.info("Failed to connect, return code %d\n", rc)

    def connect_mqtt(self) -> mqtt_client:
        client = mqtt_client.Client(self.client_id)
        client.on_connect = self.on_connect
        client.connect(self.broker, self.port)
        return client
    

    def on_message(self, client, userdata, message):
        payload = json.loads(message.payload)
        if message.topic == 'wuxi/beamLightControl':
            self.beam_control(payload)
        elif message.topic == 'wuxi/brakeLightControl':
            self.brake_control(payload)
        
        elif message.topic == 'wuxi/directionLightControl':
            self.direction_control(payload)
            
        elif message.topic == 'wuxi/wiperControl':
            self.wiper_control(payload)
            
        elif message.topic == 'wuxi/ambientControl':
            self.ambient_control(payload)
        else:
            # print(f"Received `{message.payload.decode()}` from `{message.topic}` topic")
            log.logger.info(f"Received `{message.payload.decode()}` from `{message.topic}` topic")

    def subscribe_topic_received(self, *args):
        for arg in args:
            # print('sub')
            log.logger.info('sub')
            self.client.subscribe(arg, qos=0)
            # print('ok')
            log.logger.info('ok')
            self.client.on_message = self.on_message
    
    def publish_topic(self, topic: str, msg: str):
        self.client.publish(topic, msg)
            
    def beam_control(self, payload: dict):
        # beam has three states
        status_str = payload['status']
        status = int(status_str)
        beam_topic = 'wuxi/beamLightControl/response'
        
        if status == 0:
            # turn off beamlight
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "beam is turn off"
                }
                )
            self.publish_topic(beam_topic, res)
        elif status == 1:
            # beam is on and the status is steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "hight beam light turn on success"
                }
                )
            self.publish_topic(beam_topic, res)
        elif status == 2:
            # beam is on and status is flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "low beam light turn on success"
                }
                )
            self.publish_topic(beam_topic, res)
        else:
            #publish topic 
            res = json.dumps(
                {
                    "status": 1,
                    "message": "unknow parameter value"
                }
                )
            self.publish_topic(beam_topic, res)

    def brake_control(self, payload: dict):
        brake_topic = 'wuxi/brakeLightControl/response'
        status_str = payload['status']
        status = int(status_str)
        if status == 0:
            # turn off brake light
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "brake light is turn off"
                }
                )
            self.publish_topic(brake_topic, res)
        elif status == 1:
            # steady brake light
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "brake light is turn on success"
                }
                )
            self.publish_topic(brake_topic, res)
        # elif status == 2:
        #     # flashing brake light
            
        #     #publish topic 
        #     res = json.dumps(
        #         {
        #             "status": 0,
        #             "message": "brake is flashing on"
        #         }
        #         )
        #     self.publish_topic(brake_topic, res)
        else:
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "unknow parameter value"
                }
                )
            self.publish_topic(brake_topic, res)
        
    def direction_control(self, payload: dict):
        direction_topic = 'wuxi/directionLightControl/response'
        status_str = payload['status']
        status = int(status_str)
        if status == 0:
            # turn off direction light
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "direction light turn off success"
                }
                )
            self.publish_topic(direction_topic, res)
        elif status == 1:
            # steady brake light
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "direction light turn on success"
                }
                )
            self.publish_topic(direction_topic, res)
        # elif status == 2:
        #     # flashing brake light
            
        #     #publish topic 
        #     res = json.dumps(
        #         {
        #             "status": 0,
        #             "message": "direction is flashing on"
        #         }
        #         )
        #     self.publish_topic(direction_topic, res)
        else:
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "unknow parameter value"
                }
                )
            self.publish_topic(direction_topic, res)
    
    def wiper_control(self, payload: dict):
        wiper_topic = 'wuxi/wiperControl/response'
        status_str = payload['status']
        status = int(status_str)
        if status == 0:
            # turn off wiper
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "wiper is off"
                }
                )
            self.publish_topic(wiper_topic, res)
        elif status == 1:
            # slow wiper
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "wiper run slowly speed success"
                }
                )
            self.publish_topic(wiper_topic, res)
        elif status == 2:
            # medium wiper
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "wiper run medium speed success"
                }
                )
            self.publish_topic(wiper_topic, res)
        
        elif status == 3:
            # fast wiper
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "wiper run fast speed success"
                }
                )
            self.publish_topic(wiper_topic, res)
        
        else:
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "unknow parameter value"
                }
                )
            self.publish_topic(wiper_topic, res)

    def ambient_control(self, payload: dict):
        ambient_topic = 'wuxi/ambientControl/response'
        status_str = payload['status']
        status = int(status_str)
        if status == 0:
            # turn off ambient
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is off"
                }
                )
            self.publish_topic(ambient_topic, res)
        elif status == 1:
            # ambient red steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is red light steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        elif status == 2:
            # ambient flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is red light flashing"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 3:
            # orange steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is orange steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 4:
            # orange flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is orange falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 5:
            # yellow steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is yellow steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 6:
            # yellow flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is yellow falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 7:
            # green steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is green steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 8:
            # green flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is green falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 9:
            # cyan steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is cyan steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 10:
            # cyan flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is cyan falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 11:
            # blue steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is blue steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 12:
            # blue flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is blue falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
            
        elif status == 13:
            # purple steady
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is purple steady"
                }
                )
            self.publish_topic(ambient_topic, res)
        
        elif status == 14:
            # purple flashing
            
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "ambient is purple falshing"
                }
                )
            self.publish_topic(ambient_topic, res)
            
        else:
            #publish topic 
            res = json.dumps(
                {
                    "status": 0,
                    "message": "unknow value"
                }
                )
            self.publish_topic(ambient_topic, res)
        

def run():
    broker = '192.168.211.165'
    port = 1883
    # generate client ID with pub prefix randomly
    client_id = f'python-mqtt-{random.randint(0, 100)}'
    mq = WuxiMqttClass(broker=broker, port=port, client_id=client_id)
    # print(mq)
    mq.subscribe_topic_received('wuxi/#')
    mq.client.loop_forever()
    


if __name__ == '__main__':
    # broker = '127.0.0.1'
    # port = 1883
    # # generate client ID with pub prefix randomly
    # client_id = f'python-mqtt-{random.randint(0, 100)}'
    log = Logger('log_record.log', level='debug')
    run()